home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / hplip / prnt / cups.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  20.0 KB  |  668 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import os
  5. import os.path as os
  6. import gzip
  7. import re
  8. import time
  9. import urllib
  10. import tempfile
  11. import glob
  12. from base.g import *
  13. from base import utils, models
  14.  
  15. try:
  16.     current_language = os.getenv('LANG')
  17.     newlang = 'C'
  18.     if current_language is not None and current_language.count('.'):
  19.         (newlang, encoding) = current_language.split('.')
  20.         newlang += '.UTF-8'
  21.     
  22.     os.environ['LANG'] = newlang
  23.     current_ctype = os.getenv('LC_CTYPE')
  24.     newctype = 'C'
  25.     if current_ctype is not None and current_ctype.count('.'):
  26.         (newctype, encoding) = current_ctype.split('.')
  27.         newctype += '.UTF-8'
  28.     
  29.     os.environ['LC_CTYPE'] = newctype
  30.     import cupsext
  31.     if current_ctype is not None:
  32.         os.environ['LC_CTYPE'] = current_ctype
  33.     
  34.     if current_language is not None:
  35.         os.environ['LANG'] = current_language
  36. except ImportError:
  37.     if not os.getenv('HPLIP_BUILD'):
  38.         log.warn('CUPSEXT could not be loaded. Please check HPLIP installation.')
  39.         sys.exit(1)
  40.     
  41. except:
  42.     os.getenv('HPLIP_BUILD')
  43.  
  44. IPP_PRINTER_STATE_IDLE = 3
  45. IPP_PRINTER_STATE_PROCESSING = 4
  46. IPP_PRINTER_STATE_STOPPED = 5
  47. PPD_UI_BOOLEAN = 0
  48. PPD_UI_PICKONE = 1
  49. PPD_UI_PICKMANY = 2
  50. UI_SPINNER = 100
  51. UI_UNITS_SPINNER = 101
  52. UI_BANNER_JOB_SHEETS = 102
  53. UI_PAGE_RANGE = 103
  54. UI_JOB_STORAGE_MODE = 104
  55. UI_JOB_STORAGE_PIN = 105
  56. UI_JOB_STORAGE_USERNAME = 106
  57. UI_JOB_STORAGE_ID = 107
  58. UI_JOB_STORAGE_ID_EXISTS = 108
  59. IPP_PAUSE_PRINTER = 16
  60. IPP_RESUME_PRINTER = 17
  61. IPP_PURGE_JOBS = 18
  62. CUPS_GET_DEFAULT = 16385
  63. CUPS_GET_PRINTERS = 16386
  64. CUPS_ADD_MODIFY_PRINTER = 16387
  65. CUPS_DELETE_PRINTER = 16388
  66. CUPS_GET_CLASSES = 16389
  67. CUPS_ADD_MODIFY_CLASS = 16390
  68. CUPS_DELETE_CLASS = 16391
  69. CUPS_ACCEPT_JOBS = 16392
  70. CUPS_REJECT_JOBS = 16393
  71. CUPS_SET_DEFAULT = 16394
  72. CUPS_GET_DEVICES = 16395
  73. CUPS_GET_PPDS = 16396
  74. CUPS_MOVE_JOB = 16397
  75. CUPS_AUTHENTICATE_JOB = 16398
  76. IPP_JOB_PENDING = 3
  77. IPP_JOB_HELD = 4
  78. IPP_JOB_PROCESSING = 5
  79. IPP_JOB_STOPPED = 6
  80. IPP_JOB_CANCELLED = 7
  81. IPP_JOB_ABORTED = 8
  82. IPP_JOB_COMPLETED = 8
  83. IPP_OK = 0
  84. IPP_OK_SUBST = 1
  85. IPP_OK_CONFLICT = 2
  86. IPP_OK_IGNORED_SUBSCRIPTIONS = 3
  87. IPP_OK_IGNORED_NOTIFICATIONS = 4
  88. IPP_OK_TOO_MANY_EVENTS = 5
  89. IPP_OK_BUT_CANCEL_SUBSCRIPTION = 6
  90. IPP_OK_EVENTS_COMPLETE = 7
  91. IPP_REDIRECTION_OTHER_SITE = 768
  92. IPP_BAD_REQUEST = 1024
  93. IPP_FORBIDDEN = 1025
  94. IPP_NOT_AUTHENTICATED = 1026
  95. IPP_NOT_AUTHORIZED = 1027
  96. IPP_NOT_POSSIBLE = 1028
  97. IPP_TIMEOUT = 1029
  98. IPP_NOT_FOUND = 1030
  99. IPP_GONE = 1031
  100. IPP_REQUEST_ENTITY = 1032
  101. IPP_REQUEST_VALUE = 1033
  102. IPP_DOCUMENT_FORMAT = 1034
  103. IPP_ATTRIBUTES = 1035
  104. IPP_URI_SCHEME = 1036
  105. IPP_CHARSET = 1037
  106. IPP_CONFLICT = 1038
  107. IPP_COMPRESSION_NOT_SUPPORTED = 1039
  108. IPP_COMPRESSION_ERROR = 1040
  109. IPP_DOCUMENT_FORMAT_ERROR = 1041
  110. IPP_DOCUMENT_ACCESS_ERROR = 1042
  111. IPP_ATTRIBUTES_NOT_SETTABLE = 1043
  112. IPP_IGNORED_ALL_SUBSCRIPTIONS = 1044
  113. IPP_TOO_MANY_SUBSCRIPTIONS = 1045
  114. IPP_IGNORED_ALL_NOTIFICATIONS = 1046
  115. IPP_PRINT_SUPPORT_FILE_NOT_FOUND = 1047
  116. IPP_INTERNAL_ERROR = 1280
  117. IPP_OPERATION_NOT_SUPPORTED = 1281
  118. IPP_SERVICE_UNAVAILABLE = 1282
  119. IPP_VERSION_NOT_SUPPORTED = 1283
  120. IPP_DEVICE_ERROR = 1284
  121. IPP_TEMPORARY_ERROR = 1285
  122. IPP_NOT_ACCEPTING = 1286
  123. IPP_PRINTER_BUSY = 1287
  124. IPP_ERROR_JOB_CANCELLED = 1288
  125. IPP_MULTIPLE_JOBS_NOT_SUPPORTED = 1289
  126. IPP_PRINTER_IS_DEACTIVATED = 1290
  127. CUPS_ERROR_BAD_NAME = 3840
  128. CUPS_ERROR_BAD_PARAMETERS = 3841
  129. nickname_pat = re.compile('\\*NickName:\\s*\\"(.*)"', re.MULTILINE)
  130. pat_cups_error_log = re.compile('^loglevel\\s?(debug|debug2|warn|info|error|none)', re.I)
  131. ppd_pat = re.compile('.*hp-(.*?)(-.*)+\\.ppd.*', re.I)
  132.  
  133. def getPPDPath(addtional_paths = None):
  134.     '''
  135.         Returns the CUPS ppd path (not the foomatic one under /usr/share/ppd).
  136.         Usually this is /usr/share/cups/model.
  137.     '''
  138.     if addtional_paths is None:
  139.         addtional_paths = []
  140.     
  141.     search_paths = prop.ppd_search_path.split(';') + addtional_paths
  142.     for path in search_paths:
  143.         ppd_path = os.path.join(path, 'cups/model')
  144.         if os.path.exists(ppd_path):
  145.             return ppd_path
  146.     
  147.  
  148.  
  149. def getAllowableMIMETypes():
  150.     '''
  151.         Scan all /etc/cups/*.convs files for allowable file formats.
  152.     '''
  153.     files = glob.glob('/etc/cups/*.convs')
  154.     allowable_mime_types = []
  155.     for f in files:
  156.         conv_file = file(f, 'r')
  157.         for line in conv_file:
  158.             if not line.startswith('#') and len(line) > 1:
  159.                 
  160.                 try:
  161.                     (source, dest, cost, prog) = line.split()
  162.                 except ValueError:
  163.                     continue
  164.  
  165.                 if source not in ('application/octet-stream', 'application/vnd.cups-postscript'):
  166.                     allowable_mime_types.append(source)
  167.                 
  168.             source not in ('application/octet-stream', 'application/vnd.cups-postscript')
  169.         
  170.     
  171.     allowable_mime_types.append('image/x-bmp')
  172.     allowable_mime_types.append('text/cpp')
  173.     allowable_mime_types.append('application/x-python')
  174.     allowable_mime_types.append('application/hplip-fax')
  175.     return allowable_mime_types
  176.  
  177.  
  178. def getPPDDescription(f):
  179.     if f.endswith('.gz'):
  180.         nickname = gzip.GzipFile(f, 'r').read(4096)
  181.     else:
  182.         nickname = file(f, 'r').read(4096)
  183.     
  184.     try:
  185.         desc = nickname_pat.search(nickname).group(1)
  186.     except AttributeError:
  187.         desc = ''
  188.  
  189.     return desc
  190.  
  191.  
  192. def getSystemPPDs():
  193.     (major, minor, patch) = getVersionTuple()
  194.     ppds = { }
  195.     if major == 1 and minor < 2:
  196.         ppd_dir = sys_conf.get('dirs', 'ppd')
  197.         log.debug('(CUPS 1.1.x) Searching for PPDs in: %s' % ppd_dir)
  198.         for f in utils.walkFiles(ppd_dir, pattern = 'HP*ppd*;hp*ppd*', abs_paths = True):
  199.             desc = getPPDDescription(f)
  200.             if not 'foo2' in desc and 'gutenprint' in desc.lower() or 'gutenprint' in f:
  201.                 ppds[f] = desc
  202.                 log.debug('%s: %s' % (f, desc))
  203.                 continue
  204.         
  205.     else:
  206.         log.debug('(CUPS 1.2.x) Getting list of PPDs using CUPS_GET_PPDS...')
  207.         ppd_dict = cupsext.getPPDList()
  208.         cups_ppd_path = getPPDPath()
  209.         foomatic_ppd_path = sys_conf.get('dirs', 'ppdbase', '/usr/share/ppd')
  210.         if not foomatic_ppd_path or not os.path.exists(foomatic_ppd_path):
  211.             foomatic_ppd_path = '/usr/share/ppd'
  212.         
  213.         log.debug('CUPS PPD base path = %s' % cups_ppd_path)
  214.         log.debug('Foomatic PPD base path = %s' % foomatic_ppd_path)
  215.         for ppd in ppd_dict:
  216.             if not ppd:
  217.                 continue
  218.             
  219.             if ('hp-' in ppd.lower() or 'hp_' in ppd.lower()) and ppd_dict[ppd]['ppd-make'] == 'HP':
  220.                 desc = ppd_dict[ppd]['ppd-make-and-model']
  221.                 if not 'foo2' in desc.lower() and 'gutenprint' in desc.lower() or 'gutenprint' in ppd:
  222.                     if os.path.exists(ppd):
  223.                         path = ppd
  224.                     else:
  225.                         
  226.                         try:
  227.                             path = os.path.join(foomatic_ppd_path, ppd)
  228.                         except AttributeError:
  229.                             path = ppd
  230.  
  231.                         if not os.path.exists(path):
  232.                             
  233.                             try:
  234.                                 path = os.path.join(cups_ppd_path, ppd)
  235.                             except AttributeError:
  236.                                 path = ppd
  237.  
  238.                             if not os.path.exists(path):
  239.                                 path = ppd
  240.                             
  241.                         
  242.                     ppds[path] = desc
  243.                 
  244.             'gutenprint' in ppd
  245.         
  246.     return ppds
  247.  
  248.  
  249. def levenshtein_distance(a, b):
  250.     '''
  251.     Calculates the Levenshtein distance between a and b.
  252.     Written by Magnus Lie Hetland.
  253.     '''
  254.     n = len(a)
  255.     m = len(b)
  256.     if n > m:
  257.         a = b
  258.         b = a
  259.         n = m
  260.         m = n
  261.     
  262.     current = range(n + 1)
  263.     for i in range(1, m + 1):
  264.         previous = current
  265.         current = [
  266.             i] + [
  267.             0] * m
  268.         for j in range(1, n + 1):
  269.             add = previous[j] + 1
  270.             delete = current[j - 1] + 1
  271.             change = previous[j - 1]
  272.             if a[j - 1] != b[i - 1]:
  273.                 change = change + 1
  274.             
  275.             current[j] = min(add, delete, change)
  276.         
  277.     
  278.     return current[n]
  279.  
  280. number_pat = re.compile('.*?(\\d+)', re.IGNORECASE)
  281. STRIP_STRINGS2 = [
  282.     'foomatic:',
  283.     'hp-',
  284.     'hp_',
  285.     'hp ',
  286.     '.gz',
  287.     '.ppd',
  288.     '-hpijs',
  289.     'drv:',
  290.     '-pcl',
  291.     '-pcl3',
  292.     '-jetready',
  293.     '-zxs',
  294.     '-zjs',
  295.     '-ps',
  296.     '-postscript',
  297.     '-jr',
  298.     '-lidl',
  299.     '-lidil',
  300.     '-ldl']
  301. for p in models.TECH_CLASS_PDLS.values():
  302.     pp = '-%s' % p
  303.     if pp not in STRIP_STRINGS2:
  304.         STRIP_STRINGS2.append(pp)
  305.         continue
  306.  
  307. STRIP_STRINGS = STRIP_STRINGS2[:]
  308. STRIP_STRINGS.extend([
  309.     '-series',
  310.     ' series',
  311.     '_series'])
  312.  
  313. def stripModel2(model):
  314.     model = model.lower()
  315.     for x in STRIP_STRINGS2:
  316.         model = model.replace(x, '')
  317.     
  318.     return model
  319.  
  320.  
  321. def stripModel(model):
  322.     model = model.lower()
  323.     for x in STRIP_STRINGS:
  324.         model = model.replace(x, '')
  325.     
  326.     return model
  327.  
  328.  
  329. def getPPDFile(stripped_model, ppds):
  330.     '''
  331.         Match up a model name to a PPD from a list of system PPD files.
  332.     '''
  333.     log.debug('1st stage edit distance match')
  334.     mins = { }
  335.     eds = { }
  336.     min_edit_distance = sys.maxint
  337.     log.debug('Determining edit distance from %s (only showing edit distances < 4)...' % stripped_model)
  338.     for f in ppds:
  339.         t = stripModel(os.path.basename(f))
  340.         eds[f] = levenshtein_distance(stripped_model, t)
  341.         if eds[f] < 4:
  342.             log.debug("dist('%s') = %d" % (t, eds[f]))
  343.         
  344.         min_edit_distance = min(min_edit_distance, eds[f])
  345.     
  346.     log.debug('Min. dist = %d' % min_edit_distance)
  347.     for f in ppds:
  348.         if eds[f] == min_edit_distance:
  349.             for m in mins:
  350.                 if os.path.basename(m) == os.path.basename(f):
  351.                     break
  352.                     continue
  353.             else:
  354.                 mins[f] = ppds[f]
  355.     
  356.     log.debug(mins)
  357.     if len(mins) > 1:
  358.         log.debug('2nd stage matching with model number')
  359.         
  360.         try:
  361.             model_number = number_pat.match(stripped_model).group(1)
  362.             model_number = int(model_number)
  363.         except AttributeError:
  364.             pass
  365.         except ValueError:
  366.             pass
  367.  
  368.         log.debug('model_number=%d' % model_number)
  369.         matches = { }
  370.         for x in range(3):
  371.             factor = 10 ** x
  372.             log.debug('Factor = %d' % factor)
  373.             adj_model_number = int(model_number / factor) * factor
  374.             (number_matching, match) = (0, '')
  375.             for m in mins:
  376.                 
  377.                 try:
  378.                     mins_model_number = number_pat.match(os.path.basename(m)).group(1)
  379.                     mins_model_number = int(mins_model_number)
  380.                     log.debug('mins_model_number= %d' % mins_model_number)
  381.                 except AttributeError:
  382.                     continue
  383.                 except ValueError:
  384.                     continue
  385.  
  386.                 mins_adj_model_number = int(mins_model_number / factor) * factor
  387.                 log.debug('mins_adj_model_number=%d' % mins_adj_model_number)
  388.                 log.debug('adj_model_number=%d' % adj_model_number)
  389.                 if mins_adj_model_number == adj_model_number:
  390.                     log.debug('match')
  391.                     number_matching += 1
  392.                     matches[m] = ppds[m]
  393.                     log.debug(matches)
  394.                 
  395.                 log.debug('***')
  396.             
  397.             if len(matches):
  398.                 mins = matches
  399.                 break
  400.                 continue
  401.         
  402.     
  403.     return mins
  404.  
  405.  
  406. def getPPDFile2(stripped_model, ppds):
  407.     log.debug('Matching PPD list to model %s...' % stripped_model)
  408.     matches = []
  409.     for f in ppds:
  410.         match = ppd_pat.match(f)
  411.         if match is not None:
  412.             if match.group(1) == stripped_model:
  413.                 log.debug('Found match: %s' % f)
  414.                 pdls = match.group(2).split('-')
  415.                 [](([], _[1]))
  416.             
  417.         match.group(1) == stripped_model
  418.     
  419.     log.debug(matches)
  420.     num_matches = len(matches)
  421.     if num_matches == 0:
  422.         log.error('No PPD found for model %s. Trying old algorithm...' % stripped_model)
  423.         matches = getPPDFile(stripModel(stripped_model), ppds).items()
  424.         log.debug(matches)
  425.         num_matches = len(matches)
  426.     
  427.     if num_matches == 0:
  428.         log.error('No PPD found for model %s using old algorithm.' % stripModel(stripped_model))
  429.         return None
  430.     if num_matches == 1:
  431.         log.debug('One match found.')
  432.         return (matches[0][0], '')
  433.     log.debug('%d matches found. Selecting based on PDL: Host > PS > PCL/Other' % num_matches)
  434.     for p in [
  435.         models.PDL_TYPE_HOST,
  436.         models.PDL_TYPE_PS,
  437.         models.PDL_TYPE_PCL]:
  438.         for m in matches:
  439.             for x in m[1]:
  440.                 if models.PDL_TYPES.get(x, models.PDL_TYPE_HOST) == p:
  441.                     log.debug("Selecting '-%s' PPD: %s" % (x, m[0]))
  442.                     return (m[0], '')
  443.             
  444.         
  445.     
  446.     log.debug('No specific PDL located. Defaulting to first found PPD file.')
  447.     return (matches[0][0], '')
  448.  
  449.  
  450. def getErrorLogLevel():
  451.     cups_conf = '/etc/cups/cupsd.conf'
  452.     
  453.     try:
  454.         f = file(cups_conf, 'r')
  455.     except OSError:
  456.         log.error('%s not found.' % cups_conf)
  457.     except IOError:
  458.         log.error('%s: I/O error.' % cups_conf)
  459.  
  460.     for l in f:
  461.         m = pat_cups_error_log.match(l)
  462.         if m is not None:
  463.             level = m.group(1).lower()
  464.             log.debug('CUPS error_log LogLevel: %s' % level)
  465.             return level
  466.     
  467.     log.debug('CUPS error_log LogLevel: unknown')
  468.     return 'unknown'
  469.  
  470.  
  471. def getPrintJobErrorLog(job_id, max_lines = 1000, cont_interval = 5):
  472.     ret = []
  473.     s = '[Job %d]' % job_id
  474.     cups_conf = '/var/log/cups/error_log'
  475.     
  476.     try:
  477.         f = file(cups_conf, 'r')
  478.     except (IOError, OSError):
  479.         log.error('Could not open the CUPS error_log file: %s' % cups_conf)
  480.         return ''
  481.  
  482.     if s in file(cups_conf, 'r').read():
  483.         queue = utils.Queue()
  484.         job_found = False
  485.         while True:
  486.             line = f.readline()
  487.             if s in line:
  488.                 job_found = True
  489.                 while len(queue):
  490.                     ret.append(queue.get())
  491.                 ret.append(line.strip())
  492.                 if len(ret) > max_lines:
  493.                     break
  494.                 
  495.             len(ret) > max_lines
  496.             if job_found:
  497.                 queue.put(line.strip())
  498.                 if len(queue) > cont_interval:
  499.                     break
  500.                 
  501.             len(queue) > cont_interval
  502.     
  503.     return '\n'.join(ret)
  504.  
  505.  
  506. def getDefaultPrinter():
  507.     r = cupsext.getDefaultPrinter()
  508.     if r is None:
  509.         log.debug('The CUPS default printer is not set.')
  510.     
  511.     return r
  512.  
  513.  
  514. def setDefaultPrinter(printer_name):
  515.     return cupsext.setDefaultPrinter(printer_name)
  516.  
  517.  
  518. def accept(printer_name):
  519.     return controlPrinter(printer_name, CUPS_ACCEPT_JOBS)
  520.  
  521.  
  522. def reject(printer_name):
  523.     return controlPrinter(printer_name, CUPS_REJECT_JOBS)
  524.  
  525.  
  526. def start(printer_name):
  527.     return controlPrinter(printer_name, IPP_RESUME_PRINTER)
  528.  
  529.  
  530. def stop(printer_name):
  531.     return controlPrinter(printer_name, IPP_PAUSE_PRINTER)
  532.  
  533.  
  534. def purge(printer_name):
  535.     return controlPrinter(printer_name, IPP_PURGE_JOBS)
  536.  
  537.  
  538. def controlPrinter(printer_name, cups_op):
  539.     if cups_op in (CUPS_ACCEPT_JOBS, CUPS_REJECT_JOBS, IPP_PAUSE_PRINTER, IPP_RESUME_PRINTER, IPP_PURGE_JOBS):
  540.         return cupsext.controlPrinter(printer_name, cups_op)
  541.     return 0
  542.  
  543.  
  544. def openPPD(printer):
  545.     if not printer:
  546.         return None
  547.     return cupsext.openPPD(printer)
  548.  
  549.  
  550. def closePPD():
  551.     return cupsext.closePPD()
  552.  
  553.  
  554. def getPPD(printer):
  555.     if not printer:
  556.         return None
  557.     return cupsext.getPPD(printer)
  558.  
  559.  
  560. def getPPDOption(option):
  561.     return cupsext.getPPDOption(option)
  562.  
  563.  
  564. def getPPDPageSize():
  565.     return cupsext.getPPDPageSize()
  566.  
  567.  
  568. def getPrinters():
  569.     return cupsext.getPrinters()
  570.  
  571.  
  572. def getJobs(my_job = 0, completed = 0):
  573.     return cupsext.getJobs(my_job, completed)
  574.  
  575.  
  576. def getAllJobs(my_job = 0):
  577.     return cupsext.getJobs(my_job, 0) + cupsext.getJobs(my_job, 1)
  578.  
  579.  
  580. def getVersion():
  581.     return cupsext.getVersion()
  582.  
  583.  
  584. def getVersionTuple():
  585.     return cupsext.getVersionTuple()
  586.  
  587.  
  588. def getServer():
  589.     return cupsext.getServer()
  590.  
  591.  
  592. def cancelJob(jobid, dest = None):
  593.     if dest is not None:
  594.         return cupsext.cancelJob(dest, jobid)
  595.     jobs = cupsext.getJobs(0, 0)
  596.     for j in jobs:
  597.         if j.id == jobid:
  598.             return cupsext.cancelJob(j.dest, jobid)
  599.     
  600.     return False
  601.  
  602.  
  603. def resetOptions():
  604.     return cupsext.resetOptions()
  605.  
  606.  
  607. def addOption(option):
  608.     return cupsext.addOption(option)
  609.  
  610.  
  611. def getOptions():
  612.     return cupsext.getOptions()
  613.  
  614.  
  615. def printFile(printer, filename, title):
  616.     if os.path.exists(filename):
  617.         return cupsext.printFileWithOptions(printer, filename, title)
  618.     return -1
  619.  
  620.  
  621. def addPrinter(printer_name, device_uri, location, ppd_file, model, info):
  622.     log.debug("addPrinter('%s', '%s', '%s', '%s', '%s', '%s')" % (printer_name, device_uri, location, ppd_file, model, info))
  623.     if ppd_file and not os.path.exists(ppd_file):
  624.         log.error("PPD file '%s' not found." % ppd_file)
  625.         return (-1, 'PPD file not found')
  626.     return cupsext.addPrinter(printer_name, device_uri, location, ppd_file, model, info)
  627.  
  628.  
  629. def delPrinter(printer_name):
  630.     return cupsext.delPrinter(printer_name)
  631.  
  632.  
  633. def getGroupList():
  634.     return cupsext.getGroupList()
  635.  
  636.  
  637. def getGroup(group):
  638.     return cupsext.getGroup(group)
  639.  
  640.  
  641. def getOptionList(group):
  642.     return cupsext.getOptionList(group)
  643.  
  644.  
  645. def getOption(group, option):
  646.     return cupsext.getOption(group, option)
  647.  
  648.  
  649. def getChoiceList(group, option):
  650.     return cupsext.getChoiceList(group, option)
  651.  
  652.  
  653. def getChoice(group, option, choice):
  654.     return cupsext.getChoice(group, option, choice)
  655.  
  656.  
  657. def setOptions():
  658.     return cupsext.setOptions()
  659.  
  660.  
  661. def removeOption(option):
  662.     return cupsext.removeOption(option)
  663.  
  664.  
  665. def setPasswordCallback(func):
  666.     return cupsext.setPasswordCallback(func)
  667.  
  668.